﻿using Kele.Activity.Core;
using Kele.Activity.Weixin.Service.TemplateMessage;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Senparc.CO2NET.Utilities;
using Senparc.Weixin;
using Senparc.Weixin.Exceptions;
using Senparc.Weixin.TenPay.V3;
using System;
using System.IO;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using ResponseHandler = Senparc.Weixin.TenPay.V3.ResponseHandler;
using TenPayV3Type = Senparc.Weixin.TenPay.TenPayV3Type;

namespace Kele.Activity.Weixin.Controllers.V1
{
    public class TenPayV3Controller : MvcBaseController
    {
        private static TenPayV3Info _tenPayV3Info;

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            if (errors == SslPolicyErrors.None) return true;
            return false;
        }

        public static TenPayV3Info TenPayV3Info
        {
            get
            {
                if (_tenPayV3Info == null)
                {
                    var key = "";// TenPayV3InfoCollection.GetKey(Config.SenparcWeixinSetting);

                    _tenPayV3Info =
                        TenPayV3InfoCollection.Data[key];
                }
                return _tenPayV3Info;
            }
        }

        /// <summary>
        /// JS-SDK支付回调地址（在统一下单接口中设置notify_url）
        /// </summary>
        /// <returns></returns>

        //* [appid] => wx1c870c0145984d30
        //* [bank_type] => CFT
        //* [cash_fee] => 100
        //* [fee_type] => CNY
        //* [is_subscribe] => N
        //* [mch_id] => 1297210301
        //* [nonce_str] => gkq1x5fxejqo5lz5eua50gg4c4la18vy
        //* [openid] => olSGW5BBvfep9UhlU40VFIQlcvZ0
        //* [out_trade_no] => fangchan_588796
        //* [result_code] => SUCCESS
        //* [return_code] => SUCCESS
        //* [sign] => F6890323B0A6A3765510D152D9420EAC
        //* [time_end] => 20180626170839
        //* [total_fee] => 100
        //* [trade_type] => JSAPI
        //* [transaction_id] => 4200000134201806265483331660
        //* )

        [HttpGet("PayNotifyUrl")]
        public ActionResult PayNotifyUrl()
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(HttpContext);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg = resHandler.GetParameter("return_msg");

                string res = null;

                resHandler.SetKey(TenPayV3Info.Key);
                //验证请求是否从微信发过来（安全）
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    res = "success";//正确的订单处理
                                    //直到这里，才能认为交易真正成功了，可以进行数据库操作，但是别忘了返回规定格式的消息！
                }
                else
                {
                    res = "wrong";//错误的订单处理
                }

                /* 这里可以进行订单处理的逻辑 */

                var total_fee = resHandler.GetParameter("total_fee");
                var out_trade_no = resHandler.GetParameter("out_trade_no");
                var transaction_id = resHandler.GetParameter("transaction_id");

                //发送支付成功的模板消息
                try
                {
                    string appId = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致，区分大小写。
                    string openId = resHandler.GetParameter("openid");
                    var templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "购买商品", "状态：" + return_code);
                    WeixinTrace.SendCustomLog("支付成功模板消息参数", appId + " , " + openId);
                    var result = Senparc.Weixin.MP.AdvancedAPIs.TemplateApi.SendTemplateMessage(appId, openId, templateData);
                }
                catch (Exception ex)
                {
                    WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                }

                #region 记录日志

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyXml = resHandler.ParseXML();
                    //fileStream.Write(Encoding.Default.GetBytes(res), 0, Encoding.Default.GetByteCount(res));

                    fileStream.Write(Encoding.Default.GetBytes(notifyXml), 0, Encoding.Default.GetByteCount(notifyXml));
                    fileStream.Close();
                }

                #endregion 记录日志

                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
                return Content(xml, "text/xml");
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }

        #region JsApi支付

        [HttpGet]
        [Authorize]
        [Route("JsApi")]
        public async Task<IActionResult> JsApiAsync(int activity_id, string order_id)
        {
            var timeStamp = TenPayV3Util.GetTimestamp();
            var nonceStr = TenPayV3Util.GetNoncestr();

            var record = await AppService.Record.GetRecordByOrderIdAsync(activity_id, order_id);

            var body = record.body;
            var price = decimal.ToInt32(record.pay_fee * 100);//单位：分
            var xmlDataInfo = new TenPayV3UnifiedorderRequestData(
                TenPayV3Info.AppId,
                TenPayV3Info.MchId,
                body,
                order_id,
                price,
                HttpContext.UserHostAddress()?.ToString(),
                TenPayV3Info.TenPayV3Notify,
                TenPayV3Type.JSAPI,
                openid,
                TenPayV3Info.Key,
                nonceStr);

            var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口
            var package = $"prepay_id={result.prepay_id}";
            var data = new
            {
                appId = TenPayV3Info.AppId,
                timeStamp,
                nonceStr,
                package,
                paySign = TenPayV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key)
            };

            return OkResult(data);
        }

        #endregion JsApi支付
    }
}